package bsh.asm.acessor;

import org.objectweb.asm.MethodVisitor;

import bsh.CompilationState;
import bsh.exception.CompilationFailedException;
import bsh.meta.FieldDescriptor;
import bsh.meta.TypeWrapper;
import bsh.meta.UnfinishedType;

/**
 * {@link ObjectAccessor} para um field no 'this'
 * 
 * @author takeshi
 */
public class ThisFieldObjectAcessor implements ObjectAccessor {

    private final ObjectAccessor thisAccessor, fieldAccessor;

    /**
     * C'tor
     * 
     * @param thisType o dono do field
     * @param field o {@link FieldDescriptor} acessado
     */
    public ThisFieldObjectAcessor(UnfinishedType thisType, FieldDescriptor field) {
        super();
        this.thisAccessor = new ThisObjectAccessor(thisType);
        this.fieldAccessor = new FieldObjectAcessor(field);
    }

    /**
     * {@inheritDoc}
     */
    public void loadObject(MethodVisitor visitor, CompilationState state) throws CompilationFailedException {
        this.thisAccessor.loadObject(visitor, state);
        this.fieldAccessor.loadObject(visitor, state);
    }

    /**
     * {@inheritDoc}
     */
    public TypeWrapper type() {
        return this.fieldAccessor.type();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "this (" + this.thisAccessor.type() + ")" + this.fieldAccessor;
    }

    /**
     * {@inheritDoc}
     */
    public void preStore(MethodVisitor visitor, CompilationState state) throws CompilationFailedException {
        this.thisAccessor.loadObject(visitor, state);
    }

    /**
     * {@inheritDoc}
     */
    public boolean readOnly() {
        return this.fieldAccessor.readOnly();
    }

    /**
     * {@inheritDoc}
     */
    public void storeObject(MethodVisitor visitor, CompilationState state) throws CompilationFailedException {
        this.fieldAccessor.storeObject(visitor, state);
    }

    /**
     * {@inheritDoc}
     */
    public ObjectAccessor getThisAccessor() {
        return this.thisAccessor;
    }

    /**
     * {@inheritDoc}
     */
    public ObjectAccessor getFieldAccessor() {
        return this.fieldAccessor;
    }

}
